
wbx.grid.header = (() => {
  // import
  let column, row, createDomByTagName, formatHeaderStr, menu;

  const config = {};

  const state = {
    resizeLocked: true,
    isResizeColumn: true,
    activeColumnIndex: 0, // resize used
    activeRowIndex: 0, // resize used
    resizeStartPosition: null
  };

  const dom = {
    columnHeader: null,
    rowHeader: null
  };

  // events
  const onColumnResizeBarMouseDown = (e) => {
    // 只有鼠标左键按下才行
    if (e.button === 0) {
      console.log('onColumnResizeBarMouseDown');
      state.resizeLocked = false;
      state.isResizeColumn = true;

      state.activeColumnIndex = e.target.columnIndex;
      
      state.resizeStartPosition = {
        x: e.clientX,
        y: e.clientY,
        index: state.activeColumnIndex,
        width: parseInt(column.widths[state.activeColumnIndex]) // 这个可能需要修改
      }
    }
    return false;
  };

  function onRowResizeBarMouseDown (e) {
    console.log('onRowResizeBarMouseDown');
    // 只有鼠标左键按下才行
    if (e.button === 0) {
      state.resizeLocked = false;
      state.isResizeRow = true;
  
      state.activeRowIndex = e.target.rowIndex;
      
      let startHeight = parseInt(row.heights[state.activeRowIndex])
      if (isNaN(startHeight)) {
        startHeight = e.target.parent.height;
      }
  
      state.resizeStartPosition = {
        x: e.clientX,
        y: e.clientY,
        index: state.activeRowIndex,
        height: startHeight
      }
    }
    return false;
  }

  const onGridColumnHeaderMouseDown = (e) => {
    const target = e.target;
    if (target.classList.contains('grid-column-header-cell')) {
      wbx.grid.selectOneColumn(target.index);
    }

    if (e.button === 2) {
      menu.show(e, true);
    }
    return false;
  };

  const onGridRowHeaderMouseDown = (e) => {
    const target = e.target;
    if (target.classList.contains('grid-row-header-cell')) {
      wbx.grid.selectOneRow(target.index);
    }

    // e.button: 0左键 1中键 2右键
    // see: https://developer.mozilla.org/zh-CN/docs/Web/Events/mousedown
    if (e.button === 2) {
      menu.show(e);
    }
    return false;
  }

  const init = (container) => {
    console.log('wbx.grid.header init');
    setConfig();
    render(container);
  }

  const setConfig = () => {
    column = wbx.model.column;
    row = wbx.model.row;
    createDomByTagName = wbx.util.createDomByTagName;
    formatHeaderStr = wbx.util.formatHeaderStr;
    menu = wbx.grid.menu;
  }

  const render = (container) => {
    dom.columnHeader = renderColumnHeader(container, column.count);
    dom.rowHeader = renderRowHeader(container, row.count);

    addEventListeners();
  }

  const reRender = (container) => {
    render(container);
  }

  const remove = () => {
    dom.columnHeader.remove();
    dom.rowHeader.remove();
  }

  const addEventListeners = () => {
    dom.columnHeader.onmousedown = onGridColumnHeaderMouseDown;
    dom.rowHeader.onmousedown = onGridRowHeaderMouseDown;
  };

  /**
   * 渲染行头
   * @param {*} container 
   */
  const renderRowHeader = (container, count) => {
    const rowHeader = createDomByTagName('div');
    rowHeader.classList.add('grid-row-header');
    
    rowHeader.style.gridTemplateRows = row.heights.join(' ');

    for (let i = 0; i < count; i++) {
      const rowHeaderCell = createDomByTagName('div');
      rowHeaderCell.classList.add('grid-row-header-cell');
      rowHeaderCell.classList.add('wbx-cell');
    
      rowHeaderCell.innerHTML = i + 1;
      rowHeaderCell.index = i;

      // add border
      if (i === 0) {
        rowHeaderCell.classList.add('grid-row-header-cell-first');
      }

      // 添加列头 resize bar
      addRowResizeBar(rowHeaderCell);

      rowHeader.appendChild(rowHeaderCell);
    }

    // add event
    rowHeader.oncontextmenu = (e) => { return false };

    container.appendChild(rowHeader);

    return rowHeader;
  };

  /**
   * 渲染列头
   * @param {*} container 
   */
  const renderColumnHeader = (container, count) => {
    const columnHeader = createDomByTagName('div');
    columnHeader.classList.add('grid-column-header');
    columnHeader.style.gridTemplateColumns = column.widths.join(' ');

    for (let i = 0; i < count; i++) {
      const columnHeaderCell = createDomByTagName('div');
      columnHeaderCell.classList.add('grid-column-header-cell');
      columnHeaderCell.classList.add('wbx-cell');
      const str = formatHeaderStr(i);
      columnHeaderCell.innerHTML = str;
      columnHeaderCell.index = i;

      // add border
      if (i === 0) {
        columnHeaderCell.classList.add('grid-column-header-cell-first');
      }

      // 添加行头 resize bar
      addColumnResizeBar(columnHeaderCell);

      columnHeader.appendChild(columnHeaderCell);
    }

    columnHeader.oncontextmenu = (e) => { return false };
    
    container.appendChild(columnHeader);

    return columnHeader;
  };

  const addColumnResizeBar = (container) => {
    const bar = createDomByTagName('span');
    const barInner = createDomByTagName('span');
    
    bar.classList.add('column-resize-bar');
    bar.appendChild(barInner);

    bar.columnIndex = container.index;
    barInner.columnIndex = container.index;
    
    bar.onmousedown = onColumnResizeBarMouseDown.bind(this);
    
    container.appendChild(bar);
  }

  const addRowResizeBar = (container) => {
    const bar = createDomByTagName('span');
    const barInner = createDomByTagName('span');
    
    bar.appendChild(barInner);
    bar.classList.add('row-resize-bar');
    
    bar.rowIndex = container.index;
    barInner.rowIndex = container.index;
    
    bar.onmousedown = onRowResizeBarMouseDown.bind(this);
    
    container.appendChild(bar);
  }

  const deleteRow = (index) => {};
  const deleteColumn = (index) => {};


  const highlightRow = (index) => {};
  const highlightColumn = (index) => {};

  const isResizeColumn = () => state.isResizeColumn;
  const isResizeRow = () => state.isResizeRow;
  const isResizeLocked = () => state.resizeLocked;

  const getStartPosition = () => state.resizeStartPosition;

  const lockResize = () => {
    state.resizeLocked = true;
    state.isResizeColumn = false;
    state.isResizeRow = false;
  }

  const resizeColumnHeaderWidth = (index, newWidth) => {
    console.log(newWidth + 'px');

    // modify model
    column.widths[index] = newWidth + 'px';

    // render
    dom.columnHeader.style.gridTemplateColumns = column.widths.join(' ');
  }

  const resizeRowHeaderHeight = (index, newHeight) => {
    console.log(newHeight + 'px');
    // modify model
    row.heights[index] = newHeight + 'px';
    // render
    dom.rowHeader.style.gridTemplateRows = row.heights.join(' ');
  }

  const highlightColumnHeader = (startIndex, endIndex) => {
    const children = dom.columnHeader.children;
    const end = endIndex ? endIndex : startIndex;
    for (let i = startIndex; i < end + 1; i++) {
      if (children[i]) {
        children[i].classList.add('column-active');
      }
    }
  };

  const highlightRowHeader = (startIndex, endIndex) => {
    const children = dom.rowHeader.children;
    const end = endIndex ? endIndex : startIndex;
    for (let i = startIndex; i < end + 1; i++) {
      if (children[i]) {
        children[i].classList.add('row-active');
      }
    }
  };

  const unselectColumn = (startIndex, endIndex) => {
    const children = dom.columnHeader.children;
    const end = endIndex ? endIndex : startIndex;
    for (let i = startIndex; i < end + 1; i++) {
      if (children[i]) {
        children[i].classList.remove('column-active');
      }
    }
  };

  const unselectRow = (startIndex, endIndex) => {
    const children = dom.rowHeader.children;
    const end = endIndex ? endIndex : startIndex;
    for (let i = startIndex; i < end + 1; i++) {
      if (children[i]) {
        children[i].classList.remove('row-active');
      }
    }
  }

  return {
    init: init,
    isResizeColumn: isResizeColumn,
    isResizeRow: isResizeRow,
    isResizeLocked: isResizeLocked,
    lockResize: lockResize,
    getStartPosition: getStartPosition,
    resizeColumnHeaderWidth: resizeColumnHeaderWidth,
    resizeRowHeaderHeight: resizeRowHeaderHeight,
    highlightColumnHeader: highlightColumnHeader,
    highlightRowHeader: highlightRowHeader,
    unselectColumn: unselectColumn,
    unselectRow: unselectRow,
    reRender: reRender,
    remove: remove
  };

})();